package org.springblade.modules.repair.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springblade.common.cache.DictCache;
import org.springblade.common.utils.RobotUtil;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.repair.dto.RobotContentDTO;
import org.springblade.modules.repair.dto.report.WxReportData;
import org.springblade.modules.repair.entity.*;
import org.springblade.modules.repair.enums.MaintainPlanContentEnum;
import org.springblade.modules.repair.enums.TaskStatusEnum;
import org.springblade.modules.repair.service.*;
import org.springblade.modules.repair.utils.DateUtils;
import org.springblade.modules.system.entity.DictBiz;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springblade.modules.repair.mapper.MaintainReportMapper;
import org.springframework.transaction.annotation.Transactional;

@AllArgsConstructor
@Service
public class MaintainReportServiceImpl extends BaseServiceImpl<MaintainReportMapper, MaintainReport> implements MaintainReportService {

	private final IMaintainPlanContentService planContentService;
	private final IMaintainPlanContentExtService planContentExtService;
	private final IMaintainMalfunctionWorkService malfunctionWorkService;
	private final MaintainReportSendService reportSendService;
	private final RobotUtil robotUtil;
	private final IWxFaultCauseService wxFaultCauseService;

	@Override
	public MaintainReport selectReportByWxPlan(Long planId) {
		Map<Long, List<WxFaultCause>> wxFaultCauseMap = wxFaultCauseService.list().stream().collect(Collectors.groupingBy(WxFaultCause::getId));

		MaintainReport wxReport = baseMapper.selectReportByWxPlan(planId);
		if (Func.isEmpty(wxReport)) {
			throw new ServiceException("工单信息不存在");
		}

		List<MaintainMalfunctionWork> malfunctionWorks = malfunctionWorkService.listByPlanId(planId);
		if (Func.isEmpty(malfunctionWorks)) {
			throw new ServiceException("工单信息不存在");
		}
		List<JSONObject> wxReportDataList = new ArrayList<>(malfunctionWorks.size());
		malfunctionWorks.forEach(e -> {
			if (Func.isBlank(e.getProblemItem())) {
				WxReportData wxReportData = new WxReportData();
				wxReportData.setPartsIds(e.getPartsIds());
				wxReportData.setPartsNames(e.getPartsNames());
				wxReportData.setFloorStandIds(e.getFloorStandIds());
				wxReportData.setFloorStandNames(e.getFloorStandNames());
				wxReportData.setMfDesc(e.getMfDesc());
				wxReportData.setFaultDesc(e.getFaultDesc());
				wxReportData.setPartsOpe(e.getPartsOpe());
				wxReportData.setMfImgUrl(e.getMfImgUrl());
				wxReportData.setFaultImg(e.getFaultImg());
				List<String> faultReasonList = new ArrayList<>();
				if (Func.isNotBlank(e.getFaultReasonItem())) {
					Func.toStrList(e.getFaultReasonItem()).forEach(j -> {
						List<WxFaultCause> wxFaultCauses = wxFaultCauseMap.get(Convert.toLong(j));
						if (wxFaultCauses != null && wxFaultCauses.size() > 0) {
							faultReasonList.add(wxFaultCauses.get(0).getFaultName());
						}
					});
				}
				if (Func.isNotBlank(e.getFaultReasonOtherDesc())) {
					faultReasonList.add(e.getFaultReasonOtherDesc());
				}
				if (Func.isNotEmpty(faultReasonList)) {
					wxReportData.setFaultReason(String.join(",", faultReasonList));
				}
				wxReportDataList.add((JSONObject) JSONObject.toJSON(wxReportData));
			}
		});
		wxReport.setReportData(wxReportDataList);
		return wxReport;
	}

	@Override
	public MaintainReport detail(Long reportId) {
		return baseMapper.selectReportDetail(reportId);
	}

	@Override
	public Boolean sendLog(MaintainReportSend send) {
		MaintainReport report = super.getById(send.getReportId());
		send.setRobotStatus(robotUtil.getRobotStatusV2(report.getElevatorId()) ? 1 : 2);
		send.setCreateTime(DateUtil.date());
		send.setCreateUser(AuthUtil.getUserId());
		return reportSendService.save(send);
	}

	@Override
	public Boolean sendLog(Long reportId, Integer contentType, Integer status) {
		MaintainReport report = super.getById(reportId);
		MaintainReportSend send = new MaintainReportSend();
		send.setReportId(reportId);
		send.setContentType(contentType);
		send.setStatus(status);
		send.setRobotStatus(robotUtil.getRobotStatusV2(report.getElevatorId()) ? 1 : 2);
		send.setCreateUser(AuthUtil.getUserId());
		send.setCreateTime(DateUtil.date());
		return reportSendService.save(send);
	}

	@Override
	public Boolean sendLog(Long reportId, Integer contentType, Integer status, Long userId) {
		MaintainReport report = super.getById(reportId);
		MaintainReportSend send = new MaintainReportSend();
		send.setReportId(reportId);
		send.setContentType(contentType);
		send.setStatus(status);
		send.setRobotStatus(robotUtil.getRobotStatusV2(report.getElevatorId()) ? 1 : 2);
		send.setCreateUser(userId);
		send.setCreateTime(DateUtil.date());
		return reportSendService.save(send);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean send(Long reportId) {

		Boolean result;
		MaintainReport report = super.getById(reportId);
		if (Func.isEmpty(report)) {
			throw new ServiceException("报告信息不存在");
		}
		RobotContentDTO robotContentDTO = new RobotContentDTO();
		robotContentDTO.setMaintainType(MaintainPlanContentEnum.MAINTAIN_WX.getId());
		robotContentDTO.setMaintainSubTypeDesc("【维修报告通知】");
		robotContentDTO.setLocationDesc(report.getBuildingName() + "-" + report.getElevatorAddress());
		robotContentDTO.setMaintainPersonDesc(report.getPlanUserName());
		String createTime = DateUtils.chineseDate(report.getCreateTime());
		robotContentDTO.setMaintainTimeDesc(createTime.substring(0, createTime.length() - 5));
		try {
			Boolean sendResult = robotUtil.sendRobotCardMessage(report.getTenantId(), report.getElevatorId(), reportId, robotContentDTO);
			if (sendResult) {
				this.sendLog(reportId, 1, 1);
				report.setSendStatus(2);
				result = Boolean.TRUE;
			} else {
				this.sendLog(reportId, 1, 2);
				report.setSendStatus(3);
				result = Boolean.FALSE;
			}
		} catch (Exception e) {
			this.sendLog(reportId, 1, 2);
			report.setSendStatus(3);
			result = Boolean.FALSE;
		}
		super.updateById(report);

		return result;
	}

	@Override
	public HashMap<String, Integer> selectReportByWxCount(Long planId) {
		HashMap<String, Integer> result = new HashMap<>(2);
		// 1-不需要判断 2-需要判断
		result.put("judge", 1);
		MaintainPlanContent planContent = planContentService.getById(planId);
		MaintainPlanContentExt planContentExt = planContentExtService.getOne(Wrappers.<MaintainPlanContentExt>lambdaQuery().eq(MaintainPlanContentExt::getPlanId, planId));
		if (!planContent.getStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus()) || DateUtil.parse("2024-07-23 23:59:59", "yyyy-MM-dd HH:mm:ss").getTime() < planContentExt.getPlanEndTime().getTime()) {
			return result;
		}
		Integer reportCount = baseMapper.selectReportByWxCount(planId);
		if (reportCount <= 0) {
			result.put("judge", 2);
		}
		return result;
	}

  @Override
  public List<Map<String, Object>> executeSlowQuery() {
    return baseMapper.executeSlowQuery();
  }
}
